#include "paneltask.h"
#include "dlgedittask.h"
#include "pm/manager.h"
#include <wx/tooltip.h>
#include <boost/foreach.hpp>

PanelTask::PanelTask(wxWindow* parent)
: PanelTaskGui(parent)
{
	m_listTaskTodo->InsertColumn(COL_TODO_NAME, _("Name"));
	m_listTaskTodo->InsertColumn(COL_TODO_COST, _("Cost"),      wxLIST_FORMAT_RIGHT);
	m_listTaskTodo->InsertColumn(COL_TODO_DATE, _("End date"));
	
	m_listTaskDone->InsertColumn(COL_DONE_NAME, _("Name"));
	m_listTaskDone->InsertColumn(COL_DONE_DATE, _("Date"));

	wxTheApp->Connect(pmEVT_PROJECT_LOADED, wxCommandEventHandler(PanelTask::OnProjectLoaded), NULL, this);
	
	pmConnect(pmEVT_TASK_ADDED,   pm::Task,   PanelTask::OnTaskAdded);
	pmConnect(pmEVT_TASK_UPDATED, pm::Task,   PanelTask::OnTaskUpdated);
	pmConnect(pmEVT_TASK_REMOVED, db::ID,     PanelTask::OnTaskRemoved);
}

void PanelTask::AddTaskTodo(const pm::Task& task)
{
	long item = m_listTaskTodo->InsertItem(m_listTaskTodo->GetItemCount(), wxEmptyString);
	SetTaskTodo(item, task);
}

void PanelTask::SetTaskTodo(long item, const pm::Task& task)
{
	m_listTaskTodo->SetItem(item, COL_TODO_NAME,      task.name());
	m_listTaskTodo->SetItem(item, COL_TODO_COST,      wxString::Format(wxT("%.2f"), task.cost()));
	m_listTaskTodo->SetItem(item, COL_TODO_DATE,      task.end_date().FormatISODate());

	m_listTaskTodo->SetItemData(item, task.id());
	m_listTaskTodo->SetItemBackgroundColour(item, task.end_date() <= wxDateTime::Today() ? *wxRED : *wxWHITE);
}

void PanelTask::AddTaskDone(const pm::Task& task)
{
	long item = m_listTaskDone->InsertItem(m_listTaskDone->GetItemCount(), wxEmptyString);
	SetTaskDone(item, task);
}

void PanelTask::SetTaskDone(long item, const pm::Task& task)
{
	m_listTaskDone->SetItem(item, COL_DONE_NAME, task.name());
	m_listTaskDone->SetItem(item, COL_DONE_DATE, task.end_date().FormatISODate());

	m_listTaskDone->SetItemData(item, task.id());
}

void PanelTask::OnProjectLoaded(wxCommandEvent& event)
{
	event.Skip();
wxLogMessage(wxT("PanelTask::OnProjectLoaded()"));
	m_listTaskTodo->DeleteAllItems();
	m_listTaskDone->DeleteAllItems();
	
	pm::GetTasksTodoByProject critTodo(event.GetInt());
	pm::select(critTodo);
	BOOST_FOREACH(const pm::Task& taskTodo, critTodo.m_result) {
		AddTaskTodo(taskTodo);
	}
	
	pm::GetTasksDoneByProject critDone(event.GetInt());
	pm::select(critDone);
	BOOST_FOREACH(const pm::Task& taskDone, critDone.m_result) {
		AddTaskDone(taskDone);
	}
}

void PanelTask::OnTaskAdded(pmEvent<pm::Task>& event)
{
	event.Skip();
	AddTaskTodo(event.GetContent());
}

void PanelTask::OnTaskUpdated(pmEvent<pm::Task>& event)
{
	event.Skip();
	const pm::Task& task = event.GetContent();
	long item = m_listTaskTodo->FindItem(-1, task.id());
	assert(item != wxNOT_FOUND);
	
	if (task.finished()) {
		m_listTaskTodo->DeleteItem(item);
		AddTaskDone(task);
	}
	else {
		SetTaskTodo(item, task);
	}
}

void PanelTask::OnTaskRemoved(pmEvent<db::ID>& event)
{
	event.Skip();
	long item = m_listTaskTodo->FindItem(-1, event.GetContent());
	assert(item != wxNOT_FOUND);
	m_listTaskTodo->DeleteItem(item);
}

void PanelTask::OnAddTask( wxCommandEvent& WXUNUSED(event) )
{
	DlgNewTask dlg(this);
	dlg.ShowModal();
}

void PanelTask::OnFinishTask( wxCommandEvent& WXUNUSED(event) )
{
	long item = m_listTaskTodo->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	if (item == wxNOT_FOUND)
		return;

	if (wxMessageBox(_("Are you sure you the selected task is finished ? This will put the quantity to 0"), _("Finishing task"), wxICON_EXCLAMATION|wxYES_NO) != wxYES) {
		return;
	}
	
	db::ID id = m_listTaskTodo->GetItemData(item);
	pm::Task task;
	pm::get_by_id(id, task);
	task.quantity(0.0);
	task.end_date(wxDateTime::Today());
	pm::update(task);
	
	pmEvent<pm::Task> evt(pmEVT_TASK_UPDATED, task);
	wxPostEvent(wxTheApp, evt);
}

void PanelTask::OnDelTask( wxCommandEvent& WXUNUSED(event) )
{
	long item = m_listTaskTodo->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
	if (item == wxNOT_FOUND)
		return;

	if (wxMessageBox(_("Are you sure you want to remove the selected task ? Maybe you prefer to finish it"), _("Removing task"), wxICON_EXCLAMATION|wxYES_NO) != wxYES) {
		return;
	}

	db::ID id = m_listTaskTodo->GetItemData(item);
	if (pm::remove<pm::Task>(id) == false) {
		wxLogError(wxT("Error while removing task %d !"), id);
		return;
	}
	
	pmEvent<db::ID> evt(pmEVT_TASK_REMOVED, id);
	wxPostEvent(wxTheApp, evt);
}

void PanelTask::OnItemActivated( wxListEvent& event )
{
	int id = m_listTaskTodo->GetItemData(event.GetIndex());
	wxLogMessage(wxT("PanelTask::OnItemActivated(id = %d)"), id);
	
	pm::Task task;
	if (pm::get_by_id(id, task) == false) {
		// TODO : show error
		return;
	}
	
	DlgUpdateTask dlg(this, task);
	dlg.ShowModal();
}

void PanelTask::OnMouseMotion( wxMouseEvent& event )
{
	int flags = 0;
	long item = m_listTaskTodo->HitTest(event.GetPosition(), flags, NULL);
	if (item == wxNOT_FOUND) {
		return;
	} 
	
	pm::Task task;
	pm::get_by_id(m_listTaskTodo->GetItemData(item), task);
	wxString msg;
	msg << _("Unit cost : ") << task.unit_cost() << wxT("\n")
	    << _("Quantity : ")  << task.quantity();
	m_listTaskTodo->SetToolTip(new wxToolTip(msg));
}
